home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / Graphic Elements 3 / GEBreakout / BGame.c next >
Text File  |  1995-08-22  |  7KB  |  254 lines

  1. /*
  2.     BGame.c
  3.     
  4.     Game running code for Breakout Demo
  5.     
  6.     Copyright 1994 by Al Evans. All rights reserved.
  7.     
  8.     2/24/94
  9.     
  10. */
  11.  
  12. #include "BGame.h"
  13. #include "GESound.h"
  14. #include "Motion.h"
  15.  
  16. short    gBOBrickCount;
  17. short    gBOBallCount;
  18. short    gBOBallSpeed;
  19. long    gBOScore;
  20. Str255    gBOScoreStr;
  21.  
  22. GrafElPtr MakeABrick(GEWorldPtr world, OSType id)
  23. {
  24.     GrafElPtr    aBrick;
  25.     
  26.     aBrick = FindElementByID(world, id);
  27.     if (aBrick == nil) {
  28.         aBrick = NewBasicPICT(world, id, brickPlane, rBrick, transparent, 0, 0);
  29.     }
  30.     return aBrick;
  31. }
  32.  
  33. //Setup
  34. Boolean LoadBreakoutGame(GEWorldPtr world)
  35. {
  36.     GrafElPtr    thisElement;
  37.     MParamPtr     ballMotion;
  38.     RGBColor     scoreColor;
  39.     short        scoreFNum;
  40.     
  41.     //Get background
  42.     thisElement = NewTiledGraphic(world, bkgID, bkgPlane, rBkg, srcCopy, world->animationRect);
  43.     if (thisElement == nil) return false;
  44.     
  45.     //Get paddle
  46.     thisElement = NewBasicPICT(world, paddleID, paddlePlane, rPaddle, transparent, 0, world->animationRect.bottom - 16);
  47.     if (thisElement == nil) return false;
  48.     //Set paddle's autochange proc
  49.     SetAutoChange(world, paddleID, DoPaddle, nil, 33);
  50.     
  51.     //Get ball
  52.     thisElement = NewBasicPICT(world, ballID, ballPlane, rBall, transparent, 0, 0);
  53.     if (thisElement == nil) return false;
  54.     //Hide it for now
  55.     ShowElement(world, ballID, false);
  56.     //Set ball's autochange and collision procs
  57.     ballMotion = (MParamPtr) NewPtrClear(sizeof(MotionParams));
  58.     InitMotion(ballMotion, 0, 125);
  59.     ballMotion->limitRect = world->animationRect;
  60.     SetAutoChange(world, ballID, DoBall, (Ptr) ballMotion, 17);
  61.     SetCollision(world, ballID, DoBallHit, brickPlane);  //brickPlane == paddlePlane
  62.     
  63.     //Get a brick just to make sure it's available
  64.     thisElement = MakeABrick(world, firstBrickID);
  65.     if (thisElement == nil) return false;
  66.     //Hide it
  67.     ShowElement(world, firstBrickID, false);
  68.     
  69.     //Make the scoreboard
  70.     scoreColor.red = 240 << 8;
  71.     scoreColor.green = 240 << 8;
  72.     scoreColor.blue = 46 << 8;
  73.     GetFNum("\pChicago", &scoreFNum);
  74.     thisElement = NewTextGraphic(world, scoreID, scorePlane, 20, 10, srcOr, 
  75.                         scoreFNum, bold, 12, scoreColor, gBOScoreStr);
  76.     if (thisElement == nil) return false;
  77.     SetAutoChange(world, scoreID, DoScore, nil, 200);  //Update score 5 times/second
  78.     
  79.     return true;
  80. }
  81.  
  82. void MakeNewBricks(GEWorldPtr world)
  83. {
  84.     GrafElPtr    thisBrick;
  85.     OSType        currBrickID = firstBrickID;
  86.     short        rowCount, colCount;
  87.     
  88.     gBOBrickCount = 0;
  89.     for (rowCount = 0; rowCount < 5; rowCount++) 
  90.         for (colCount = 0; colCount < 10; colCount++) {
  91.         thisBrick = MakeABrick(world, currBrickID);
  92.         if (thisBrick == nil) return;                 //Oops
  93.         MoveElementTo(world, currBrickID, 2 + colCount * 34, 36 + rowCount * 18);
  94.         ShowElement(world, currBrickID, true);
  95.         currBrickID++;
  96.         gBOBrickCount++;
  97.     }
  98. }
  99.  
  100. void StartNewBall(GEWorldPtr world)
  101. {
  102.     GrafElPtr    ball;
  103.     MParamPtr    ballMotion;
  104.     
  105.     ball = FindElementByID(world, ballID);
  106.     if (ball == nil) return;                        //Oops again
  107.     MoveElementTo(world, ballID, 0, 200);
  108.     ShowElement(world, ballID, true);
  109.     ballMotion = (MParamPtr) ball->changeData;
  110.     ballMotion->currMotion.v = gBOBallSpeed;
  111.     ballMotion->currMotion.h = gBOBallSpeed - 2;
  112. }
  113.  
  114. void NewBreakoutGame(GEWorldPtr world)
  115. {
  116.     
  117.     gBOScore = 0;
  118.     gBOScoreStr[0] = 0;
  119.     gBOBallCount = 4;
  120.     gBOBallSpeed = 4;
  121.     MakeNewBricks(world);
  122.     StartNewBall(world);
  123. }
  124.  
  125. //Return position of mouse in GEWorld coordinates
  126. short    GetPlayerMove(GEWorldPtr world)
  127. {
  128.     GrafPtr        savePort;
  129.     Point        saveFocus;
  130.     Point        mousePt;
  131.     short        move;
  132.  
  133.  
  134.     GetPort(&savePort);
  135.     SetPort(world->gEWPort);
  136.     GetGEWorldFocus(world, &saveFocus);
  137.     FocusOnGEWorld(world);
  138.  
  139.     GetMouse(&mousePt);
  140.     move = mousePt.h;
  141.     SetGEWorldFocus(world, saveFocus);
  142.     SetPort(savePort);
  143.     return move;
  144. }
  145.  
  146. pascal void DoPaddle(GEWorldPtr world, GrafElPtr paddle)
  147. {
  148.     short paddleX;
  149.     short limit = world->animationRect.right - (paddle->animationRect.right - paddle->animationRect.left);
  150.     
  151.     paddleX = GetPlayerMove(world);
  152.     if (paddleX < 0) paddleX = 0;
  153.     if (paddleX > limit) paddleX = limit;
  154.     PtrMoveElementTo(world, paddle, paddleX, paddle->animationRect.top, false);
  155. }
  156.  
  157.  
  158. pascal void DoBall(GEWorldPtr world, GrafElPtr ball)
  159. {
  160.     MParamPtr    motion = (MParamPtr) ball->changeData;
  161.     
  162.         switch (CheckLimits(&ball->animationRect, &motion->limitRect)) {
  163.             case up:
  164.                 if (motion->currMotion.v < 0)
  165.                     motion->currMotion.v = -motion->currMotion.v;
  166.                 break;
  167.             case left:
  168.                 if (motion->currMotion.h < 0)
  169.                     motion->currMotion.h = -motion->currMotion.h;
  170.                 break;
  171.             case down:
  172.                 ShowElement(world, ball->objectID, false);
  173.                 //Do something gamey here
  174.                 if (--gBOBallCount > 0)
  175.                     StartNewBall(world);
  176.                 break;
  177.             case right:
  178.                 if (motion->currMotion.h > 0)
  179.                     motion->currMotion.h = -motion->currMotion.h;
  180.                 break;
  181.         }
  182.         
  183.         PtrMoveElement(world, ball, motion->currMotion.h, motion->currMotion.v);
  184.  
  185. }
  186.  
  187. pascal void DoBallHit(GEWorldPtr world, GrafElPtr ball, GEDirection dir, CollisionPhase phase, GrafElPtr objHit)
  188. {
  189.     MParamPtr    motion = (MParamPtr) ball->changeData;
  190.     short         hBump;
  191.     
  192.     if (phase == collisionBegin) {
  193.         if (objHit->objectID == paddleID) {            //Ball hit the paddle
  194.             if (world->userData != nil)
  195.                 GEScheduleSound((GESoundPtr) world->userData, rPaddle, 1, 0);
  196.             hBump = ball->animationRect.left - objHit->animationRect.left + 6;
  197.             hBump = hBump - 20;
  198.             hBump = hBump / 4;
  199.             motion->currMotion.h += hBump;
  200.         }
  201.         else {                                         //Ball hit a brick
  202.             if (world->userData != nil)
  203.                 GEScheduleSound((GESoundPtr) world->userData, rBall, 1, 0);
  204.             ShowElement(world, objHit->objectID, false);
  205.             gBOScore += 50;
  206.             --gBOBrickCount;
  207.             if (gBOBrickCount == 0) {
  208.                 gBOBallSpeed++;
  209.                 MakeNewBricks(world);
  210.                 StartNewBall(world);
  211.             }
  212.         }    
  213.         //Either way, bounce ball
  214.         switch (dir) {
  215.             case left:
  216.             case upLeft:
  217.             case downLeft:
  218.                 if (motion->currMotion.h < 0)
  219.                     motion->currMotion.h = -motion->currMotion.h;
  220.                 if (dir != left)
  221.                     motion->currMotion.v = -motion->currMotion.v;
  222.                 break;
  223.             case right:
  224.             case upRight:
  225.             case downRight:
  226.                 if (motion->currMotion.h > 0)
  227.                     motion->currMotion.h = -motion->currMotion.h;
  228.                 if (dir != right)
  229.                     motion->currMotion.v = -motion->currMotion.v;
  230.                 break;
  231.             case up:
  232.                 if (motion->currMotion.v < 0)
  233.                     motion->currMotion.v = -motion->currMotion.v;
  234.                 break;
  235.             case down:
  236.                 if (motion->currMotion.v > 0)
  237.                     motion->currMotion.v = -motion->currMotion.v;
  238.                 break;
  239.         }
  240.             
  241.     }
  242. }
  243.  
  244. pascal void DoScore(GEWorldPtr world, GrafElPtr scoreBoard)
  245. {
  246.     static long scoreShown = 0;
  247.     
  248.     if (gBOScore != scoreShown) {
  249.         scoreShown = gBOScore;
  250.         NumToString(scoreShown, gBOScoreStr);
  251.         SetTextGraphicText(world, scoreBoard->objectID, gBOScoreStr);
  252.     }
  253. }
  254.